package lambda_expression.stream;

import java.util.*;
import java.util.function.Function;
import java.util.function.IntConsumer;
import java.util.function.IntFunction;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * <p>
 *     Stream常见操作API介绍
 *     1. 聚合操做
 *     2. stream的处理流程
 *          - 数据源
 *          - 数据转换
 *          - 获取结果
 *     3. 获取Stream对象
 *          1. 从集合或者数组中获取
 *              Collection.stream()，如accounts.stream()
 *              Collection.parallelStream()
 *              Arrays.stream(T t)
 *          2. BufferReader
 *                  BufferReader.lines - > stream()
 *          3. 静态工厂
 *              java.util.stream.InputStream.range()
 *              java.nio.file.Files.walk()
 *          4. 自定构建
 *              java.util.Spliterator
 *          5. 更多方式
 *              Random.ints()
 *              Pattern.splitAsStream()
 *      4. 中间操作API （intermediate）
 *          操作结果是一个Stream，中间操作可以有一个或多个连续的中间操作，需要注意的是，中间操作只记录操作方式，
 *          不做具体的执行，直到结束操作发生时，才做数据的最终执行。
 *          【中间操作】就是业务逻辑处理
 *          中间操作过程：
 *              无状态：数据处理时，不受前置中间操作的影响。
 *                  map/filter/peek/parallel/sequential/unordered
 *              有状态：数据处理时吗，受前置操作的影响
 *                  distinct/sorted/limit/skip
 *
 *      5. 终结操作|结束操作（terminal）
 *          需要注意：一个Stream对象，只能有一个Terminal操作，这个操作一旦发生，就会真实的处理数据，生成对应的处理结果。
 *          终结操作：
 *              非短路操作：当前Stream对象必须处理完结合中所有的数据，才能得到处理结果。
 *                  forEach/forEachOrdered/toArray/reduce/collect/min/max/count/iterator/
 *              短路操作：当前的Stream对象在处理过程中，一旦满足某个条件，就可以得到结果。
 *                  anyMatch/allMatch/noneMatch/findFirst/findAny
 * </p>
 */
public class StreamApiTest {
    public static void main(String[] args) {
        // 批量数据 -> Stream对象
        Stream<String> stream = Stream.of("admin", "tom", "guoguo");
//        System.out.println(stream.filter(s -> s.length() > 3).allMatch(s -> s.length()>3));

        // 数组
        String[] strArrays = new String[] { "刘备", "张飞", "关羽" };
        Arrays.stream(strArrays);

        // 列表
        List<String> list = new ArrayList<String>(){
            {
                add("曹操");
                add("孙权");
                add("刘备");
                add("诸葛亮");
            }
        };
        list.stream();

        // 集合
        Set<String> set = new HashSet<String>(){
            {
                add("诸葛亮");
                add("司马懿");
            }
        };
        set.stream();

        // Map
        Map<String, Integer> map = new HashMap<String, Integer>(){
            {
                put("tom", 100);
                put("jack", 1300);
                put("lucy", 50);
            }
        };
        Stream mapStream = map.entrySet().stream();

        //////////////////// Stream 对象对于基本数据类型的功能封装 ///////////////////
        IntStream.of(12,3,4,76,5,65).forEach(new IntConsumer() {
            @Override
            public void accept(int value) {
                System.out.println(value);
            }
        });
        IntStream.of(12,3,4,76,5,65).forEach(System.out::println);
        IntStream.of(12,3,4,76,5,65).forEach(System.out::println);
        IntStream.range(1,10).forEach(Model::println);
        IntStream.rangeClosed(1,10).forEach(Model::println);

        // Stream对象 ---> 转换得到指定的数据类型
        // 数组
//        Object[] objs = stream.toArray(String[]::new);
        // 字符串
//        String s = stream.collect(Collectors.joining("="));
//        System.out.println(s);

        // 列表
//        List<String> listx = stream.collect(Collectors.toList());
        // 集合
//        Set<String> setx = stream.collect(Collectors.toSet());
        // Map
        Map<String, Integer> mapx = (Map<String, Integer>) mapStream.collect(Collectors.toMap(x -> x, y -> y));
        System.out.println(mapx);

    }
}

class Model{
    public static void println(int x) {
        System.out.println("-----" + x);
    }
}
